package com.iximo.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.iximo.client.desktop.DesktopClient;
import com.iximo.domain.Book;
import com.iximo.domain.Books;
import com.iximo.domain.Category;
import com.iximo.domain.Chapter;
import com.iximo.domain.Comments;
import com.iximo.domain.Member;
import com.iximo.openAPI.IximoOpenAPIGet;
import com.iximo.openAPI.IximoOpenAPIPost;
import com.iximo.openAPI.impl.IximoOpenAPIGetImpl;
import com.iximo.openAPI.impl.IximoOpenAPIPostImpl;

import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.OAuthServiceProvider;
import net.oauth.client.OAuthClient;
import net.oauth.client.httpclient4.HttpClient4;


public class OpenAPIClient {
	private String callBack;
	private OAuthServiceProvider provider;
	private OAuthConsumer consumer;
	private static final String JSONPARAM = "format=json";
	
	private static final IximoOpenAPIGet apiGet = new IximoOpenAPIGetImpl();
	private static final IximoOpenAPIPost apiPost = new IximoOpenAPIPostImpl();
	
	public OpenAPIClient(String callBack, String key, String screct) {
		this.callBack = callBack;
		this.provider = new OAuthServiceProvider(
				"http://api.iximo.com/request_token.php", 
				"http://api.iximo.com/authorize.php",
				"http://api.iximo.com/access_token.php");
		this.consumer = new OAuthConsumer(
				this.callBack, 
				key, 
				screct, 
				this.provider);
	}
	
	private OAuthMessage oauth(String serviceURL, String method, boolean oauth) {
		DesktopClient client = new DesktopClient(this.consumer);
		client.setOAuthClient(new OAuthClient(new HttpClient4()));
		OAuthMessage response = null;
		try {
			if(oauth){
				response = client.access(method, serviceURL, null);
			} else {
				response = client.accessWithNoAuth(method, serviceURL, null);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return response;
	}
	
	private OAuthMessage oauthPost(String serviceURL, String method, Collection<? extends Entry> parameters) {
		DesktopClient client = new DesktopClient(this.consumer);
		client.setOAuthClient(new OAuthClient(new HttpClient4()));
		OAuthMessage response = null;
		try {
			response = client.access(method, serviceURL, parameters);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return response;
	}
	
	/**
	 * open api
	 */
	//get
	public String downloadBook(int bookId) throws Exception {
		String uri = BaseUrl.getBookdownloadUrl + "?book_id=" + bookId;
		InputStream inStream = InternetService.get(uri);
		String downloadUrl = InternetService.readStream(inStream);
		return downloadUrl;
	}
	
	public Book getBookInfo(int bookId) throws Exception {
		String uri = BaseUrl.getBookInfoUrl + "?book_id=" + bookId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, false);
		Book book = apiGet.getBookInfoData(inStream);
		return book;
	}
	
	public List<Book> getBookByNum(int bookId, int num) throws Exception {
		String uri = BaseUrl.getBookOtherPeopleListUrl + "?book_id=" + bookId + "&num=" + num; 
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Book> book = apiGet.getBookByNumData(inStream);
		return book;
	}
	
	/**
	 * get response stream 
	 */
	private InputStream getStream(String uri, String method, boolean oauth) throws Exception {
		OAuthMessage response = oauth(uri, method, oauth);
		return response.getBodyAsStream();
	}
	
	//get json data's url
	private static String getJsonUrl(String url, String json) {
		String jsonUrl = url;
		if("json".equals(json))
			jsonUrl += ((url.indexOf("?") > 0) ? "&" : "?") + JSONPARAM;
		return jsonUrl;
	}
	
	public List<Book> getBooksByCategary(int categoryId, String sort, int page,
			int pageSize, String json) throws Exception {
		String uri = "";
//		String uri = BaseUrl.getBookCategorySortListUrl + 
//							"?cate_id=" + categoryId + "&sort=" + sort + "&page=" + page + "&pagesize=" + pageSize;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, true);
		List<Book> books = apiGet.getBooksByCategaryData(inStream);
		return books;
	}
	
	public List<Category> getAllCategory(int parentId) throws Exception {
		String uri = BaseUrl.getBookCategorysUrl + "?parent_id=" + parentId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Category> categories = apiGet.getAllCategoryData(inStream);
		return categories;
	}
	
	public List<Book> getBookListByType(String type, int page, int pageSize)
	throws Exception {
		String uri = BaseUrl.getBookSortListUrl + "?type=" + type + "&page=" + page + "&pagesize=" + pageSize;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Book> book = apiGet.getBookListByTypeData(inStream);
		return book;
	}
	
	public List<Chapter> getChapter(int bookId) throws Exception {
		String uri = BaseUrl.getBookChaptersUrl + "?book_id=" + bookId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Chapter> chapter = apiGet.getChapterData(inStream);
		return chapter;
	}
	
	public String getChapterContent(int chapterId) throws Exception {
		String uri = BaseUrl.getBookChapterContentUrl + "?chapter_id=" + chapterId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		return apiGet.getChapterContentData(inStream);
	}
	
	public Comments getComment(int bookId, int page, int pagesize) throws Exception {
		String uri = BaseUrl.getBookCommentsUrl + "?book_id=" + bookId + "&page=" + page + "&pagesize=" + pagesize;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		Comments comments = apiGet.getCommentData(inStream);
		return comments;
	}
	
	public List<Book> searchBook(String keyWords) throws Exception {
		String uri = BaseUrl.searchBookUrl + "?search_val=" + keyWords;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Book> books = apiGet.searchBookData(inStream);
		return books;
	}
	
	public List<Book> getBookMark(int page, int pageSize) throws Exception {
		String uri = BaseUrl.myBookMarkUrl + "?page=" + page + "&pagesize=" + pageSize;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Book> books = apiGet.getBookMarkData(inStream);
		return books;
	}
	
	public int addBookMark(int bookId, int chapterId) throws Exception {
		String uri = BaseUrl.addBookMarUrl + "?book_id=" + bookId + "&chapter_id=" + chapterId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		String ret = InternetService.readStream(inStream);
		return Integer.valueOf(ret);
	}
	
	public List<Book> getFavoriteBook(int page, int pageSize) throws Exception {
		String uri = BaseUrl.myFavoriteUrl + "?page=" + page + "&pagesize=" + pageSize;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Book> book = apiGet.getFavoriteBookData(inStream);
		return book;
	}
	
	public int addFavoriteBook(int bookId) throws Exception {
		String uri = BaseUrl.addFavoriteUrl + "?book_id=" + bookId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		String ret = InternetService.readStream(inStream);
		return Integer.valueOf(ret);
	}
	
	public int deleteFavorite(int favoriteId) throws Exception {
		String uri = BaseUrl.deleteFavariteUrl + "?f_id=" + favoriteId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		String ret = InternetService.readStream(inStream);
		return Integer.valueOf(ret);
	}
	
	public int addVote(int bookId) throws Exception {
		String uri = BaseUrl.addVoteUrl + "?book_id=" + bookId;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		String ret = InternetService.readStream(inStream);
		return Integer.valueOf(ret);
	}
	
	public List<Books> getDownloadList() throws Exception {
		String uri = BaseUrl.myDownloadListUrl;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Books> books = apiGet.getDownloadListData(inStream);
		return books;
	}
	
	public Books getHotBoooks(String type, int recomment, int newbook) throws Exception {
		String uri = BaseUrl.getHotBookListUrl + "?type=" + type + "&rec_size=" + recomment + "&new_size=" + newbook;
//		String uri = "http://www2.iximo.cc/smartphone/html/hit_hot.xml";
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		Books books = apiGet.getHotBoooksData(inStream);
		return books;
	}
	
	public int randBook(int score, int bookId) throws Exception {
		String uri = BaseUrl.addRatingUrl + "?book_id=" + bookId + "&score=" + score;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		String ret = InternetService.readStream(inStream);
		return Integer.valueOf(ret);
	}
	
	public String getMemberBalance(String key) throws Exception {
		String uri = BaseUrl.myBalanceUrl + "?key=b2b0acc3a188e051fd461c36dfccd897"; 
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	
	public List<Chapter> getBuyChapterList(int bookId, String key) throws Exception {
		String uri = BaseUrl.getBookVipChapterUrl + "?book_id=" + bookId + "&key=" + "b2b0acc3a188e051fd461c36dfccd897" ;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Chapter> chapters = apiGet.getBuyChapterListData(inStream);
		return chapters;
	}
	
	public List<Chapter> payChapterList(int bookId, String key, String...chapterIds) throws Exception {
		StringBuilder chaIds = new StringBuilder();
		for(String chaId : chapterIds){
			chaIds.append(chaId).append(',');
		}
		chaIds.deleteCharAt(chaIds.length()-1);
		String uri = BaseUrl.payBookUrl + "?book_id=" + bookId + "&cha_ids=" + chaIds.toString() + "&key=b2b0acc3a188e051fd461c36dfccd897";
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		List<Chapter> chapters = apiGet.payChapterListData(inStream);
		return chapters;
	}
	
	public String getNotic() throws Exception {
		String uri = BaseUrl.getNoticeUrl;
		InputStream inStream = getStream(uri, OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String getCurrentIphoneVersion() throws Exception {
		String uri = BaseUrl.getIphoneVersionUrl;
		InputStream inStream = getStream(uri, OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	
	
	//get start-------------------->>
	public String get_user_info(String json) throws Exception {
		String uri = BaseUrl.get_user_info;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	
	public String get_user_favorite(int page, int pagesize, String json) throws Exception {
		String uri = BaseUrl.get_user_favorite + "?page=" + page + "&pagesize=" + pagesize;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	
	public String delete_user_favorite(int f_id, String json) throws Exception {
		String uri = BaseUrl.delete_user_favorite + "?f_id=" + f_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.DELETE, true);
		return InternetService.readStream(inStream);
	}
	
	public String get_user_book_mark(int page, int pagesize, String json) throws Exception {
		String uri = BaseUrl.get_user_book_mark + "?page=" + page + "&pagesize=" + pagesize;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String delete_user_book_mark(int f_id, String json) throws Exception {
		String uri = BaseUrl.delete_user_book_mark + "?f_id=" + f_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.DELETE, true);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_comment(int book_id, int page, int pagesize, String json) throws Exception {
		String uri = BaseUrl.get_book_comment + "?book_id=" + book_id + "&page=" + page + "&pagesize=" + pagesize;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_info(int book_id, String json) throws Exception {
		String uri = BaseUrl.get_book_info + "?book_id=" + book_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_category(String json) throws Exception {
		String uri = BaseUrl.get_book_category;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_chapter_content(String chapter_id, String json) throws Exception {
		String uri = BaseUrl.get_book_chapter_content + "?chapter_id=" + chapter_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_chapters_list(int book_id, String json) throws Exception {
		String uri = BaseUrl.get_book_chapters_list + "?book_id=" + book_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_vip_chapters_list(int book_id, String json) throws Exception {
		String uri = BaseUrl.get_book_vip_chapters_list + "?book_id=" + book_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_download_url(int book_id, String json) throws Exception {
		String uri = BaseUrl.get_book_download_url + "?book_id=" + book_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_user_book_download_list(int page, int pagesize, String json) throws Exception {
		String uri = BaseUrl.get_user_book_download_list + "?page=" + page + "&pagesize=" + pagesize;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	
	public String search(String search_type, String search_val, String json) throws Exception {
		String uri = BaseUrl.search + "?search_type=" + search_type + "&search_val=" + search_val;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_message(String type, int msg_id, String json) throws Exception {
		String uri = BaseUrl.get_message + "?type=" + type + "&msg_id=" + msg_id;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	
	public String update_user_info(String username, int gender, String qq,
			String msn, String phone, String address, String json) throws Exception {
		String uri = BaseUrl.update_user_info +
		"?username=" + username +
		"&gender=" + gender +
		"&qq=" + qq +
		"&msn=" + msn +
		"&phone=" + phone +
		"&address=" + address;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.PUT, true);
		return InternetService.readStream(inStream);
	}
	
	public String get_gift_list(String json) throws Exception {
		String uri = BaseUrl.get_gift_list;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_book_category_sort_list(int cate_id, String sort, int page, int pagesize, String json) throws Exception {
		String uri = BaseUrl.get_book_category_sort_list + "?cate_id=" + cate_id + "&sort=" + sort + "&page=" + page
		+ "&pagesize=" + pagesize;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, false);
		return InternetService.readStream(inStream);
	}
	
	public String get_message(String type, int page, int pagesize, String json)  throws Exception {
		String uri = BaseUrl.get_message + "?type=" + type + "&page=" + page + "&pagesize=" + pagesize;
		InputStream inStream = getStream(getJsonUrl(uri, json), OAuthMessage.GET, true);
		return InternetService.readStream(inStream);
	}
	//get end----------->>
	
	//post start------------->>
	public String send_gift(int gid, String to_user_id, int book_id, String json) throws Exception {
		String serviceURL = BaseUrl.send_gift;
		Map map = new HashMap();
		map.put("gid", String.valueOf(gid));
		map.put("to_user_id", to_user_id);
		map.put("book_id", String.valueOf(book_id));
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream(); 
		return InternetService.readStream(ins);
	}
	
	public String send_message(int to_user_id, String title, String content, int parent_id, String json) throws Exception {
		String serviceURL = BaseUrl.send_message;
		Map map = new HashMap();
		map.put("to_user_id", String.valueOf(to_user_id));
		map.put("title", title);
		map.put("content", content);
		map.put("parent_id", String.valueOf(parent_id));
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream(); 
		return InternetService.readStream(ins);
	}
	
	public String user_regedit(String email, String password, String json) throws Exception {
		String serviceURL = BaseUrl.user_regedit;
		Map map = new HashMap();
		map.put("email", email);
		map.put("password", password);
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream(); 
		return InternetService.readStream(ins);
	}
	
	public String add_book_rating(int book_id, int score, String json) throws Exception {
		String serviceURL = BaseUrl.add_book_rating;
		Map map = new HashMap();
		map.put("book_id", String.valueOf(book_id));
		map.put("score", String.valueOf(score));
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream();
		return InternetService.readStream(ins);
	}
	
	public String add_user_favorite(int book_id, String json) throws Exception {
		String serviceURL = BaseUrl.add_user_favorite;
		Map map = new HashMap();
		map.put("book_id", book_id);
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream();
		return InternetService.readStream(ins);
	}
	
	public String add_user_book_mark(int book_id, String chapter_id, String json) throws Exception {
		String serviceURL = BaseUrl.add_user_book_mark;
		Map map = new HashMap();
		map.put("book_id", String.valueOf(book_id));
		map.put("chapter_id", chapter_id);
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream();
		return InternetService.readStream(ins);
	}
	
	public String add_book_vote(int book_id, String json) throws Exception {
		String serviceURL = BaseUrl.add_book_vote;
		Map map = new HashMap();
		map.put("book_id", String.valueOf(book_id));
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream();
		return InternetService.readStream(ins);
	}
	
	public String add_book_comment(int book_id, String comment_id, String comment, String json) throws Exception {
		String serviceURL = BaseUrl.add_book_vomment;
		Map map = new HashMap();
		map.put("book_id", String.valueOf(book_id));
		map.put("comment_id", comment_id);
		map.put("comment", comment);
		map.put("format", json);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, getParams(map));
		InputStream ins = response.getBodyAsStream();
		return InternetService.readStream(ins);
	}
	
	//post end--------------->>
	
	
	public Member login(int clientType, String email, String password, String json) throws Exception {
		String serviceURL = BaseUrl.loginUrl + "?client_type=" + clientType;
		Map map = new HashMap();
		map.put("email", email);
		map.put("password", password);
		List parameters = getParams(map);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, parameters);
		InputStream ins = response.getBodyAsStream();
		Member member = apiPost.loginData(ins);
		return member;
	}
	
	public int sendComment(int bookId, String comment, int commentId, String json) throws Exception {
		String serviceURL = BaseUrl.addCommentUrl;	
		Map params = new HashMap();
		params.put("comment", comment);
		params.put("book_id", String.valueOf(bookId));
		params.put("comment_id", String.valueOf(commentId));
		List parameters = getParams(params);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, parameters);
		InputStream inStream = response.getBodyAsStream();
		String ret = InternetService.readStream(inStream);
		return Integer.valueOf(ret);
	}
	
	public Member register(int clientType, String email, String password, String json) throws Exception {
		String serviceURL = BaseUrl.registerUrl + "?client_type=" + clientType;
		Map params = new HashMap();
		params.put("email", email);
		params.put("password", password);
		List parameters = getParams(params);
		OAuthMessage response = oauthPost(serviceURL, OAuthMessage.POST, parameters);
		InputStream inStream = response.getBodyAsStream();
		Member member = apiPost.registerData(inStream);
		return member;
	}
	
	public int modifyProfile(String username, int gender, String qq,
			String msn, String phone, String json) throws Exception {
		String uri = BaseUrl.update_user_info;
		Map params = new HashMap();
		params.put("username", username);
		params.put("gender", String.valueOf(gender));
		params.put("qq", qq);
		params.put("msn", msn);
		params.put("phone", phone);
		List parameters = getParams(params);
		OAuthMessage response = oauthPost(uri, OAuthMessage.POST, parameters);
		InputStream inStream = response.getBodyAsStream();
		String ret = InternetService.readStream(inStream);
		if(ret != null && !"".equals(ret)) {
			return Integer.valueOf(ret);
		}
		return 0;
	}
	
	/**
	 * get post parameters
	 */
	private List getParams(Map map) {
		List params =  new ArrayList();
		Set entries = map.entrySet();
		Iterator iter = entries.iterator();
		while(iter.hasNext()){
			Map.Entry entry = (Map.Entry)iter.next();
			params.add(entry);
		}
		return params;
	}
	
}
